home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / graph_alg / _embedding.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  6.1 KB  |  257 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _embedding.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. /*******************************************************************************
  17. *                                                                              *
  18. *  EMBEDDING   (straight line embedding)                                       *
  19. *                                                                              *
  20. *  K. Mehlhorn (1989)                                                          *
  21. *                                                                              *
  22. *******************************************************************************/
  23.  
  24. #include <LEDA/graph_alg.h>
  25.  
  26.  
  27. const int A = -2; 
  28. const int B = -1; 
  29.  
  30. static node_array<list_item>  Classloc;
  31. static node_array<int>  ord, labelled, Class;
  32. static node_array<node> first, second, last;
  33. static edge_array<edge> reversal;
  34.  
  35. void label_node(graph& G, list<node>& L, int& count,
  36.                 list<node>& Al,list<node>& Bl,list<node>*& Il,
  37.                 node v, node c)
  38.  
  39. { // labels the node v; c is the special node which is to be labelled
  40.   // last; the details are described in lemma 10
  41.   edge e;
  42.   L.append(v);
  43.   ord[v]=count++; 
  44.   labelled[v]=1;
  45.  
  46.   forall_adj_edges(e,v)
  47.   { edge e1 = reversal[e];
  48.     node tt = target(e);
  49.     int i;
  50.  
  51.     if (labelled[tt] && !labelled[target(G.cyclic_adj_succ(e))])
  52.       { first[v]=tt; 
  53.         second[v]=target(G.cyclic_adj_pred(e));
  54.        }
  55.  
  56.     if (labelled[tt] && !labelled[target(G.cyclic_adj_pred(e))]) last[v]=tt;
  57.  
  58.     if (!labelled[tt] && (tt != c))
  59.       { if (Class[tt] == A) 
  60.           { Al.del(Classloc[tt]); 
  61.             Classloc[tt] = Bl.push(tt);
  62.             Class[tt]=B;
  63.            }  
  64.         else 
  65.           { if (Class[tt] == B) 
  66.                { Bl.del(Classloc[tt]);
  67.                  i = 2-labelled[target(G.cyclic_adj_succ(e1))]
  68.                       -labelled[target(G.cyclic_adj_pred(e1))];
  69.                 }
  70.             else 
  71.                { i=Class[tt];
  72.                  Il[i].del(Classloc[tt]);
  73.                  i = i+1-labelled[target(G.cyclic_adj_succ(e1))]
  74.                         -labelled[target(G.cyclic_adj_pred(e1))];
  75.                 }
  76.  
  77.              Class[tt]=i;
  78.              Classloc[tt]=Il[i].push(tt);
  79.  
  80.            }//end else case
  81.  
  82.       }//end if
  83.  
  84.   }//end 
  85.  
  86. }//end of label_node
  87.  
  88.  
  89. void compute_labelling(graph& G,list<node>& L, list<node>& Pi)
  90. { /* computes the ordering of lemma 10 in List L ,the sequence pi
  91.      in List Pi, the function L^-1(v) in Array ord, and the functions
  92.      first,second,last of lemma 11 in the corresponding Arrays
  93.    */
  94.   node v,a,b,c;
  95.  
  96.   /* zuerst berechne ich die drei Knoten,die am Rand des aeusseren 
  97.      Gebiets liegen sollen
  98.    */
  99.  
  100.   a=G.first_node();
  101.   list<edge> temp = G.adj_edges(a);
  102.   b = target(temp.pop());
  103.   c = target(temp.pop());
  104.  
  105.  
  106. /*
  107.   node_array<int> labelled(G,0);
  108. */
  109.  
  110.   labelled.init(G,0);
  111.  
  112.   int count = 0;
  113.   
  114.   list<node> Al ;
  115.  
  116. /*
  117.   node_array<int> Class(G); 
  118.   node_array<list_item> Classloc(G);
  119. */
  120.  
  121.   Class.init(G); 
  122.   Classloc.init(G);
  123.  
  124.   forall_nodes(v,G) { Classloc[v] = Al.push(v);Class[v]=A;}
  125.  
  126.   list<node> Bl;
  127.   list<node>* Il = new list<node>[G.number_of_nodes()];
  128.   
  129.   label_node(G,L,count,Al,Bl,Il,a,c);
  130.   label_node(G,L,count,Al,Bl,Il,b,c);
  131.  
  132.   while (v=Il[1].pop()) label_node(G,L,count,Al,Bl,Il,v,c);
  133.  
  134.   label_node(G,L,count,Al,Bl,Il,c,c);
  135.  
  136.    //nun berechne ich noch first second und last des Knoten c 
  137.   first[c]=a;
  138.   last[c]=b;
  139.  
  140.   edge e;
  141.   forall_adj_edges(e,c) if (target(e)==a) second[c]=target(G.cyclic_adj_pred(e));
  142.   
  143.  //nun die Folge Pi
  144.   node_array<list_item> Piloc(G);
  145.   Piloc[a] = Pi.push(a);
  146.   Piloc[b] = Pi.append(b);
  147.   forall(v,L) if (v != a && v != b) Piloc[v] = Pi.insert(v,Piloc[second[v]],-1);
  148.  
  149. }//end of compute_labelling 
  150.  
  151. void move_to_the_right(list<node>& Pi, node v, node w, 
  152.                        node_array<int>& ord, node_array<int>& x)
  153.  
  154. { //increases the x-coordinate of all nodes which follow w in List Pi
  155.   //and precede v in List L,i.e., have a smaller ord value than v
  156.   int seen_w = 0;
  157.   node z;
  158.   forall(z,Pi)
  159.   { if (z==w) seen_w=1;
  160.     if (seen_w && (ord[z]<ord[v])) x[z]=x[z]+1;
  161.   }
  162. }
  163.  
  164.  
  165. int STRAIGHT_LINE_EMBEDDING(graph& G,node_array<int>& x, node_array<int>& y)
  166. {
  167.  // computes a straight-line embedding of the planar map G into
  168.  // the 2n by n grid. The coordinates of the nodes are returned
  169.  // in the Arrays x and y. Returns the maximal coordinate.
  170.  
  171. list<node> L;
  172. list<node> Pi;
  173. list<edge> TL;
  174.  
  175. node v;
  176. edge e;
  177. int maxcoord=0;
  178.  
  179. /*
  180. node_array<int>  ord(G);
  181. node_array<node> first(G), second(G), last(G);
  182. */
  183.  
  184. ord.init(G);
  185. first.init(G);
  186. second.init(G);
  187. last.init(G);
  188.  
  189.  
  190. TL = TRIANGULATE_PLANAR_MAP(G);
  191.  
  192. /*
  193. edge_array<edge> reversal(G);
  194. */
  195.  
  196. reversal.init(G);
  197. compute_correspondence(G,reversal);
  198.  
  199. compute_labelling(G,L,Pi);
  200.  
  201.  
  202. //I now embed the first three nodes
  203.  
  204. v = L.pop();
  205. x[v]=y[v]=0;
  206.  
  207. v=L.pop();
  208. x[v]=2;y[v]=0;
  209.  
  210. v=L.pop();
  211. x[v]=y[v]=1;
  212.  
  213. //I now embed the remaining nodes
  214.  
  215. while (v=L.pop())
  216.  { // I first move the nodes depending on second[v] by one unit
  217.    // and the the nodes depending on last[v] by another unit to the 
  218.    // right
  219.  
  220.    move_to_the_right(Pi,v,second[v],ord,x);
  221.    move_to_the_right(Pi,v,last[v],ord,x);
  222.  
  223.    // I now embed v at the intersection of the line with slope +1
  224.    // through first[v] and the line with slope -1 through last[v]
  225.  
  226.    int x_first_v = x[first[v]];
  227.    int x_last_v =  x[last[v]];
  228.    int y_first_v = y[first[v]];
  229.    int y_last_v =  y[last[v]];
  230.  
  231.    x[v]=(y_last_v - y_first_v + x_first_v + x_last_v)/2;
  232.    y[v]=(x_last_v - x_first_v + y_first_v + y_last_v)/2;
  233.  }
  234.  
  235. // delete triangulation edges
  236.  
  237. forall(e,TL) G.del_edge(e);
  238.  
  239. forall_nodes(v,G) maxcoord = Max(maxcoord,Max(x[v],y[v]));
  240. return maxcoord;
  241.  
  242. }
  243.  
  244.  
  245.  
  246. int STRAIGHT_LINE_EMBEDDING(graph& G,node_array<double>& x, node_array<double>& y)
  247. { node v;
  248.   node_array<int> x0(G), y0(G);
  249.  
  250.   int result = STRAIGHT_LINE_EMBEDDING(G,x0,y0);
  251.  
  252.   forall_nodes(v,G) { x[v] = x0[v];
  253.                       y[v] = y0[v]; }
  254.   return result;
  255. }
  256.